import { SerialNoMaker } from './../common/serialNoMaker';
import { ObjectCopier } from './../common/objectCopier';
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { ServiceBase } from "./serviceBase";
import { Order, Cart, Table, DataContextManager } from "../model/clerkDataContext";
import { TableParty, SerialNoEntity } from './../model/clerkDataContext';
import { guid } from "../common/guid";
import { CacheManager } from "../common/cacheManager";

@Injectable()
export class TableService extends ServiceBase {
    constructor(protected http: Http) { super(); }
    /**
     * 开台
     * @param tableId 台桌Id
     * @param headCount 人数
     */
    OpenTable(tableId: string, headCount: number): Promise<{
        table: Table;
        masterOrder: Order;
        tableParty: TableParty;
    }> {
        let url = "api/table/openTable";
        let serialNo = SerialNoMaker.Current.getNewSerialNo();
        let waiter = [];
        if(this.CurrentUser){
            waiter.push(this.CurrentUser);
        }
        let postJson = {
            id: tableId,
            headCount: headCount,
            serialNo: serialNo.sernialNo,
            sourceid: "mpj/clerk",
            waiter: waiter
        };
        return this.Put(url, postJson);
    };
    CloseTable(tableId: string): Promise<{ table: Table }> {
        var url = "api/table/closeTable";
        let postJson = {
            id: tableId
        };
        return this.Put(url, postJson);
    };
    GetTableZoneList() {
        let url = "api/table/getTableZoneList";
        return this.Get(url);
    };
    async GetTableList(params: { tableZoneId?: string, tableStatus?: string }) {
        let url = "api/table/getTableList";
        if (params) {
            url = url + "/";
            url += params.tableZoneId ? params.tableZoneId : "";
            // url += params.tableStatus ? "/" + params.tableStatus : "";
        }
        let result = [];
        let tables = await this.Get(url);
        return tables;
    }
    async GetTableInfo(tableId: string) {
        let url = "api/table/getTableInfo/" + tableId;
        let tbItem = await this.Get(url);
        await this.updateInvtInfo(tbItem);
        console.log(tbItem);
        return tbItem;
    }

    async updateInvtInfo(table: Table) {
        let invtList = CacheManager.Current.get("invtList")
        if (!invtList) {
            invtList = await DataContextManager.Current.ClerkCtx.Inventory.ToList();
            CacheManager.Current.add({ key: "invtList", value: invtList });
        }
        if ((<any>table).orderList) {
            for (let item of (<any>table).orderList) {
                for (let cItem of item.cart.items) {
                    if ((!cItem.inventory.id || !cItem.inventory.pic) && cItem.inventoryId != "0000000000000000000000000000000") {
                        let inventory = invtList.find(x => x.id == cItem.inventoryId);
                        cItem.inventory = inventory;
                    }
                }
            }
        }
    }

    async updateTableHeadCount(table: Table) {
        let url = "api/table/updateHeadCount";
        let params = {
            masterOrderId: table.masterOrder.id,
            headCount: table.masterOrder.extended.headCount
        }
        return await this.Put(url, params);

    }
    /**
     * 转台
     * @param oldTableId
     * @param newTable
     * @param sucb
     * @param errcb
     */
    TransferTable(oldTableId: string, newTable: { id: string, name: string }): Promise<{
        oldTable: Table;
        oldTableParty: TableParty;
        newTable: Table;
        newTableParty: TableParty;
        masterOrder: Order;
        preOrderList: Order[];
    }> {
        let url = "api/table/transferTable";
        let postJson = {
            oldTable: { id: oldTableId },
            newTable: newTable
        };

        return this.Put(url, postJson);
    }
    /**
     * 取消并台
     * @param tableId
     * @param sucb
     * @param errcb
     */
    CancelMergeTable(table: Table) {
        let url = "api/table/cancelMergeTable";
        let params = {
            tableId: table.id,
            tablePartyId: (<any>table).tableParty.id,
            tableGroupId: (<any>table).tableParty.tableGroupId,
            masterOrderId: table.masterOrder.id
        }
        if ((<any>table).orderList && (<any>table).orderList.length) {
            (<any>params).preOrderCount = (<any>table).orderList.length;
        }
        return this.Put(url, params);
    }
    /**
     * 并台
     * @param mainTableId
     * @param tableList
     * @param sucb
     * @param errcb
     */
    MergeTable(mainTableId: string, tableList: [{ id: string }]): Promise<{ tableList: Table[], tablePartyList: TableParty[] }> {
        let url = "api/table/mergeTable";
        let postJson = {
            mainTable: { id: mainTableId },
            tableList: tableList
        }
        return this.Put(url, postJson);
    }

    GetGroupTables(tableGroupId: string) {
        let url = "api/table/getGroupTables/" + tableGroupId;
        return this.Get(url);
    }

    /**
     * 下单
     * @param order 
     * @param table
     */
    async Ordering(order: Order, table: Table): Promise<Order> {
        let url = "api/order/ordering";
        let waiter = [];
        if(this.CurrentUser){
            waiter.push(this.CurrentUser);
        }
        let extended = {
            waiter: waiter,
            tableParty: table.tableParty
        }
        let postJson: any = {
            table: { id: table.id },
            storeId: this.CurrentStore.id,
            creator: this.CurrentUser,
            sourceid: "mpj/clerk",
            description: order.description,
            id: order.id,
            extended: extended
        };

        let orderCopy = ObjectCopier.Copy<any>(order);
        for (let item of orderCopy.cart.items) {
            if (item.inventory.pic) {
                delete item.inventory.pic;
            }
            if (item.inventory.categories && item.inventory.categories.length) {
                this.deleteCatePic(item.inventory.categories);
            }
            if (item.extended && item.extended.categories && item.extended.categories.length) {
                this.deleteCatePic(item.extended.categories);
            }
        }

        postJson.cart = orderCopy.cart;

        return this.Post(url, postJson);
    }

    /**
     * 并台情况下，下单到多个台桌
     */
    async mergeOrdering(order: Order, tables: Table[]) {
        let url = "api/order/mergerOrdering";
        let orderCopy = ObjectCopier.Copy<any>(order);
        for (let item of orderCopy.cart.items) {
            if (item.inventory.pic) {
                delete item.inventory.pic;
            }
            if (item.inventory.categories && item.inventory.categories.length) {
                this.deleteCatePic(item.inventory.categories);
            }
            if (item.extended && item.extended.categories && item.extended.categories.length) {
                this.deleteCatePic(item.extended.categories);
            }
        }
        let postParams = {
            terminal: this.Terminal,
            user: this.CurrentUser,
            orderList: []
        }

        tables.forEach(tab => {
            let serialNo: SerialNoEntity = null;
            if (tab.masterOrder.serialNo) {
                serialNo = SerialNoMaker.Current.getNewSerialNo(tab.masterOrder.serialNo);
            }
            orderCopy = ObjectCopier.Copy<any>(orderCopy);
            orderCopy.id = guid();
            if (orderCopy.cart.items) {
                orderCopy.cart.items.forEach(item => {
                    item.id = guid();
                })
            }
            orderCopy.serialNo = serialNo ? serialNo.domain + "-" + serialNo.sernialNo : "";
            orderCopy.sourceid = "mpj/clerk";
            orderCopy.storeId = this.CurrentStore.id;
            orderCopy.creator = this.CurrentUser;
            orderCopy.table = { id: tab.id };
            orderCopy.terminal = this.Terminal;
            postParams.orderList.push({ tableId: tab.id, preOrder: orderCopy });
        });
        return this.Post(url, postParams);
    }

    /**
     * 删除base64图片信息，确保请求FBS的请求体不超限
     */
    deleteCatePic(categories) {
        try {
            for (let cate of categories) {
                if (cate.parent && cate.parent.store) {
                    delete cate.parent.store.owner.pic;
                }
            }
        } catch (e) {
            console.log(e);
        }
    }
    /**
     * 台桌上菜
     * @param invertoryId 菜品Id
     * @param orderId 订单Id
     * @param count 数量
     */
    Served(invertoryId: string, cartItemId: string, orderId: string, count: number) {
        let url = "api/table/served";
        let postJson = {
            invertoryId: invertoryId,
            orderId: orderId,
            count: count,
            operator: this.CurrentUser,
            cartItemId: cartItemId
        };

        return this.Put(url, postJson);
    }

    /**
     * 批量上菜
     * @param params 请求参数
     */
    batchServed(params: {
        invertoryId: string;
        count: number;
        cartItemId: string;
        orderId: string;
        operator;
    }) {
        let url = "api/table/batchServed";
        let putJson: any = {
            params: params
        }
        return this.Put(url, putJson);
    }

    /**
     * 取消上菜
     * @param invertoryId
     * @param orderId
     */
    CancelServed(invertoryId: string, orderId: string) {
        let url = "api/table/cancelServed";
        let postJson = {
            invertoryId: invertoryId,
            orderId: orderId
        };

        return this.Put(url, postJson);
    }
    /**
     * 催菜
     * @param  {string} orderId  订单的id
     * @param  {} cartItemList  需要催菜的项
     */
    RemindOrder(orderId: string, cartItemList) {
        let url = "api/order/reminderOrder";
        let params = {
            orderId: orderId,
            storeId: this.CurrentStore.id,
            opeartor: this.CurrentUser,
            cartItemList: cartItemList
        }
        return this.Post(url, params);
    }
    /**
     * 退单
     * @param  {Cart} cartItem
     * @param  {Order} preOrder
     */
    RefundOrder(cartItem: Cart, preOrder: Order, refundReason?: string) {
        let url = "api/order/refundOrder";
        let postJson = <any>{
            refOrderId: [{ id: preOrder.id }],
            extended: preOrder.extended,
            storeId: preOrder.storeId,
            creator: preOrder.cashier,
            cart: {
                items: [cartItem]
            }
        };
        if (refundReason) {
            postJson.refundCause = refundReason;
        } else {
            postJson.refundCause = "";
        }
        return this.Post(url, postJson);
    }

    /**
     * 合并preorder和refundorder
     */
    mergeOrderList(orderList) {
        let preOrders = [];
        let refundOrders = [];
        let result = [];
        if (orderList && orderList.length) {
            preOrders = orderList.filter(function (item) {
                return item.orderType == "pre-order";
            });
            refundOrders = orderList.filter(function (item) {
                return item.orderType == "pre-order-refund";
            })
        }

        for (let order of preOrders) {
            let targetRefunds = refundOrders.filter(ele => { return ele.refOrderId[0].id == order.id });
            if (targetRefunds && targetRefunds.length) {
                targetRefunds.forEach(refund => {
                    order.cart.qty += refund.cart.qty ? refund.cart.qty : 0;
                    if (order.cart.qty > 0) {
                        order.amountDue += refund.amountDue;
                    }
                });
            }
            order.amountDue = order.amountDue > 0 ? order.amountDue : 0;
            result.push(order);
        }

        return result;
    }

    /**
     * 叫起等叫的菜
     * @param table 当前台桌 
     * @param cartListItem  购物车列表项 
     */
    pickup(table, cartListItem) {
        let url = "api/order/pickup";
        let postParams = {
            orderId: table.masterOrder.id,
            cartItemList: cartListItem,
            terminal: this.Terminal,
            user: this.CurrentUser
        }
        return this.Post(url, postParams);
    }
    /**
     * 结束台桌待清台状态
     * @param table 
     */
    finishCleanTable(tableId) {
        let url = "api/table/finishCleanTable";
        let postParams = {
            tableId: tableId
        }
        return this.Post(url, postParams);
    }
}
